package com.example.questionsystem.modules.qu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.questionsystem.modules.qu.Vo.QuestionVO;
import com.example.questionsystem.modules.qu.dto.QuestionBankDto;
import com.example.questionsystem.modules.qu.dto.QuestionDTO;
import com.example.questionsystem.modules.qu.entity.ExtractionConfig;
import com.example.questionsystem.modules.qu.entity.QuestionBanks;
import com.example.questionsystem.modules.qu.entity.SubjectSessions;
import com.example.questionsystem.modules.qu.enums.QuestionTypeEnum;
import com.example.questionsystem.modules.qu.mapper.QuestionBankMapper;
import com.example.questionsystem.modules.qu.service.QuestionBankService;
import com.example.questionsystem.modules.qu.service.SubjectsService;
import com.example.questionsystem.modules.qu.service.util.AdvancedContentExtractor2;
import com.example.questionsystem.modules.qu.service.util.ChineseNumberConverter;

import com.example.questionsystem.modules.qu.util.QuestionParser;
import lombok.Data;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class QuestionBankServiceImpl extends ServiceImpl<QuestionBankMapper, QuestionBanks>  implements QuestionBankService {


    @Resource
    private QuestionBankMapper questionBankMapper;


    @Resource
    private SubjectsService subjectsService;

    /**
     * 批量保存题目
     * 1. 判断题
     * 2. 单选题
     * 3. 多选题
     * 4. 填空题
     * 5. 简答题
     * 6. 论述题
     * 7. 计算题
     * 9. 其他题
     * @param questionBankDto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchSave(QuestionBankDto   questionBankDto) {
        // 基础参数校验
        if (questionBankDto == null) {
            throw new com.example.questionsystem.core.exception.ServiceException("请求参数不能为空");
        }
        String projectId = questionBankDto.getProjectId();
        String subjectId = questionBankDto.getSubjectId();
        SubjectSessions subjectSessionsById = subjectsService.getSubjectSessionsById(subjectId);
        if (subjectSessionsById == null) {
            throw new com.example.questionsystem.core.exception.ServiceException("未找到科目模板，请先在考前模板中配置该科目: " + subjectId);
        }
        if (subjectSessionsById.getProjectId() == null || !subjectSessionsById.getProjectId().equals(projectId)) {
            throw new com.example.questionsystem.core.exception.ServiceException("科目不属于当前项目，请检查模板绑定。当前项目: " + projectId);
        }

        // 题型模板校验（确保按照模板识别并传入了各题型的键）
        if (questionBankDto.getQuestionCategory() == null) {
            throw new com.example.questionsystem.core.exception.ServiceException("题型分类未配置，请按模板识别并传入题型分类");
        }
        validateQuestionCategoryKeys(questionBankDto.getQuestionCategory());

        // 通过全部校验后，再删除已有题目，避免误删
        deleteBySubjectQuestion(subjectId);
        String[] projectSplit = projectId.split("_");

        String SessionsNumber = ChineseNumberConverter.extractAndConvertChineseNumber(subjectSessionsById.getSessionName());
        // 判断题
        processJudgmentQuestions(questionBankDto, projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 单选题
        processSingleChoiceQuestions(questionBankDto, projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 多选题
        processMultipleChoiceQuestions(questionBankDto, projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 填空题
        processFillBlankQuestions(questionBankDto, projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 表格题
        processTableQuestions(questionBankDto, projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 不定项
        processNotChoiceQuestions(questionBankDto, projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 综合题
        processGenericQuestions(questionBankDto.getQuestionCategory().getComprehensiveQuestions().get("综合题"),
                "综合题", projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        // 简答题
        processGenericQuestions(questionBankDto.getQuestionCategory().getShortAnswerQuestions().get("简答题"),
                "简答题", projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);
        //写作题
        processGenericQuestions(questionBankDto.getQuestionCategory().getWritingQuestions().get("写作题"),
                "写作题", projectId, subjectId, projectSplit, SessionsNumber, subjectSessionsById);

    }

    @Override
    public void updateQuestionContent(String questionId, String questionHtml) {
        if (questionId == null || questionId.trim().isEmpty()) {
            throw new com.example.questionsystem.core.exception.ServiceException("题目ID不能为空");
        }
        if (questionHtml == null) {
            questionHtml = "";
        }

        // 与入库逻辑保持一致，规范化HTML并提取纯文本
        String normalizedHtml = com.example.questionsystem.modules.qu.service.util.AdvancedContentExtractor2.extractContentHTML(
                questionHtml.replaceAll(">\\s+<", "><")
        );
        String plainText = Jsoup.parse(normalizedHtml).text();

        UpdateWrapper<QuestionBanks> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("question_id", questionId)
                .set("question_html", normalizedHtml)
                .set("question_text", plainText);

        int rows = questionBankMapper.update(null, updateWrapper);
        if (rows == 0) {
            throw new com.example.questionsystem.core.exception.ServiceException("未找到题目或更新失败: " + questionId);
        }
    }

    /**
     * 校验题型分类中是否包含模板要求的键，缺失时抛出业务异常
     */
    private void validateQuestionCategoryKeys(com.example.questionsystem.modules.qu.Vo.QuestionCategory category) {
        java.util.List<String> missing = new java.util.ArrayList<>();

        // 判断题
        if (category.getJudgmentQuestions() == null || !category.getJudgmentQuestions().containsKey("判断题")) {
            missing.add("判断题");
        }
        // 单项选择题
        if (category.getSingleChoiceQuestions() == null || !category.getSingleChoiceQuestions().containsKey("单项选择题")) {
            missing.add("单项选择题");
        }
        // 多项选择题
        if (category.getMultipleChoiceQuestions() == null || !category.getMultipleChoiceQuestions().containsKey("多项选择题")) {
            missing.add("多项选择题");
        }
        // 填空题
        if (category.getBlankQuestion() == null || !category.getBlankQuestion().containsKey("填空题")) {
            missing.add("填空题");
        }
        // 表格题
        if (category.getTableQuestions() == null || !category.getTableQuestions().containsKey("表格题")) {
            missing.add("表格题");
        }
        // 不定项
        if (category.getNotChoiceQuestions() == null || !category.getNotChoiceQuestions().containsKey("不定项")) {
            missing.add("不定项");
        }
        // 综合题
        if (category.getComprehensiveQuestions() == null || !category.getComprehensiveQuestions().containsKey("综合题")) {
            missing.add("综合题");
        }
        // 简答题
        if (category.getShortAnswerQuestions() == null || !category.getShortAnswerQuestions().containsKey("简答题")) {
            missing.add("简答题");
        }
        // 写作题
        if (category.getWritingQuestions() == null || !category.getWritingQuestions().containsKey("写作题")) {
            missing.add("写作题");
        }

        if (!missing.isEmpty()) {
            throw new com.example.questionsystem.core.exception.ServiceException("题型模板缺失: " + String.join("、", missing) + "。请按模板配置后再保存");
        }
    }

    private void processTableQuestions(QuestionBankDto questionBankDto, String projectId, String subjectId, String[] projectSplit, String sessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, "表格题");

        AtomicInteger counter = new AtomicInteger(questionCount);
        questionBankDto.getQuestionCategory().getTableQuestions().get("表格题").forEach(question -> {
            QuestionBanks questionBanks = new QuestionBanks();
            Document doc = Jsoup.parse(question);
            doc.outputSettings(new Document.OutputSettings().prettyPrint(false));


            StringBuilder questionHtml = new StringBuilder();
            questionBanks.setProjectId(projectId);
            questionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                    + sessionsNumber+ "_" +
                    subjectSessionsById.getKmxh() + "_"+QuestionTypeEnum.getCodeByName("表格题")+"_" + counter.incrementAndGet());

            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(doc.outerHtml()));
            questionBanks.setQuestionText(doc.text());
            questionBanks.setOptionsHtml("");
            questionBanks.setOptionsHtml("");
            questionBanks.setQuestionType("表格题");
            questionBanks.setSubjectId(subjectId);
            // 修改提取逻辑以支持嵌套标签结构
            String answerText = extractContent(doc, "答案：");
            String scoreText = extractContent(doc, "分数：");
            String knowledgeText = extractContent(doc, "知识点：");
            // 设置提取到的信息，如不存在则为空字符串
            questionBanks.setAnswer(answerText);
            questionBanks.setScore(scoreText);
            questionBanks.setKnowledge(knowledgeText);
            questionBanks.setChildCount("0");
            questionBanks.setUsageCount("0");
            questionBanks.setParentId("");
            save(questionBanks);
        });
    }

    private void processNotChoiceQuestions(QuestionBankDto questionBankDto, String projectId, String subjectId, String[] projectSplit, String sessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, "不定项");
        AtomicInteger counter = new AtomicInteger(questionCount);
        questionBankDto.getQuestionCategory().getNotChoiceQuestions().get("不定项").forEach(question -> {
            QuestionBanks questionBanks = new QuestionBanks();
            Document doc = Jsoup.parse(question);
            doc.outputSettings(new Document.OutputSettings().prettyPrint(false));
            Elements PElement = doc.select("p");
            StringBuilder questionHtml = new StringBuilder();
            StringBuilder option = new StringBuilder();
            StringBuilder optionHtml = new StringBuilder();

            questionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                    + sessionsNumber + "_" +
                    subjectSessionsById.getKmxh() + "_"+QuestionTypeEnum.getCodeByName("不定项") +"_" + counter.incrementAndGet());

            PElement.forEach(p -> {
                String text = p.text().trim();
                // 精确匹配段落开头（支持中文冒号和空格）
                if (text.startsWith("答案：")
                        || text.startsWith("分数：")
                        || text.startsWith("知识点：")) {

                } else if (text.matches("^[A-Z][\\.．,，].*")) {
                    // 处理选项
                    option.append(p.text());
                    optionHtml.append(p.outerHtml());
                } else {
                    // 保留题目正文
                    questionHtml.append(p.outerHtml());
                }
            });
            // 修改提取逻辑以支持嵌套标签结构
            String answerText = extractContent(doc, "答案：");
            String scoreText = extractContent(doc, "分数：");
            String knowledgeText = extractContent(doc, "知识点：");

            // 设置提取到的信息，如不存在则为空字符串
            questionBanks.setAnswer(answerText);
            questionBanks.setScore(scoreText);
            questionBanks.setKnowledge(knowledgeText);
            questionBanks.setProjectId(projectId);
            questionBanks.setOptions(option.toString());
            questionBanks.setQuestionText(PElement.get(0).text());
            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.toString()));
            questionBanks.setOptionsHtml(AdvancedContentExtractor2.removePStyles2(optionHtml.toString()));
            questionBanks.setQuestionType("不定项");
            questionBanks.setSubjectId(subjectId);
            questionBanks.setUsageCount("0");
            questionBanks.setChildCount("0");
            questionBanks.setParentId("");
            save(questionBanks);
        });
    }
    private void processGenericQuestions(List<String> questions, String questionType,
                                         String projectId, String subjectId, String[] projectSplit,
                                         String SessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, questionType);
        AtomicInteger counter = new AtomicInteger(questionCount);
        questions.forEach(html -> {
            try {
                QuestionParser.Question question = QuestionParser.parseQuestion(html);
                String stemHtml = question.getStemHtml();//题干HTML
                List<QuestionParser.SubQuestion> subQuestions = question.getSubQuestions();//小题HTML
                 QuestionBanks MasterquestionBanks = new QuestionBanks();
                MasterquestionBanks.setProjectId(projectId);
                MasterquestionBanks.setSubjectId(subjectId);
                MasterquestionBanks.setQuestionType(questionType);
                MasterquestionBanks.setQuestionText(Jsoup.parse(stemHtml).text());
                stemHtml = stemHtml.replaceAll(">\\s+<", "><");
                MasterquestionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(stemHtml));
                if(subQuestions == null ||  subQuestions.size() == 0) {
                    MasterquestionBanks.setChildCount("1");
                }else {
                    MasterquestionBanks.setChildCount(String.valueOf(subQuestions.size()));
                }
                MasterquestionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                        + SessionsNumber + "_" +
                        subjectSessionsById.getKmxh() + "_"+ QuestionTypeEnum.getCodeByName(questionType) +"_" + counter.incrementAndGet());
                MasterquestionBanks.setOptionsHtml("");
                MasterquestionBanks.setOptions("");
                MasterquestionBanks.setKnowledge("");
                MasterquestionBanks.setAnswer("");
                MasterquestionBanks.setScore("");
                MasterquestionBanks.setUsageCount("0");
                MasterquestionBanks.setParentId("");
                save(MasterquestionBanks);
                AtomicInteger SubCounter = new AtomicInteger();
                subQuestions.forEach(subQuestion -> {
                    QuestionBanks questionBanks = new QuestionBanks();
                    questionBanks.setProjectId(projectId);
                    questionBanks.setSubjectId(subjectId);
                    questionBanks.setChildCount("0");
                    if (subQuestion.getType().equals("单项选择题") || subQuestion.getType().equals("多项选择题") || subQuestion.getType().equals("不定项")) {
                        questionBanks.setQuestionId(MasterquestionBanks.getQuestionId()+"_"+
                                SubCounter.incrementAndGet());
                        questionBanks.setQuestionType(subQuestion.getType());
                        QuestionHtml questionHtml = getOptionsHtml(subQuestion.getHtml());
                        questionBanks.setQuestionText(questionHtml.getQuestionText());
                        questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.getQuestionHtml().replaceAll(">\\s+<", "><")));
                        questionBanks.setOptionsHtml(questionHtml.getOptionHtml());
                        questionBanks.setOptions(questionHtml.getOptions());
                    }
                    if (subQuestion.getType().equals("填空题")) {
                        questionBanks.setQuestionId(MasterquestionBanks.getQuestionId()+"_"+
                                SubCounter.incrementAndGet());
                        questionBanks.setQuestionType(subQuestion.getType());
                        QuestionHtml questionHtml = getOptionsHtml(subQuestion.getHtml());
                        int bracketCount = countEmptyBrackets(questionHtml.getQuestionText());
                        questionBanks.setQuestionText(questionHtml.getQuestionText());
                        questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.getQuestionHtml().replaceAll(">\\s+<", "><")));
                        questionBanks.setOptionsHtml("");
                        questionBanks.setOptions(questionHtml.getOptions());
                        questionBanks.setChildCount(String.valueOf(bracketCount));
                    }
                    if (subQuestion.getType().equals("简答题")
                            || subQuestion.getType().equals("写作题")
                            || subQuestion.getType().equals("综合题") || subQuestion.getType().equals("表格题")) {
                        questionBanks.setQuestionId(MasterquestionBanks.getQuestionId()+"_"+
                                SubCounter.incrementAndGet());
                        questionBanks.setQuestionType(subQuestion.getType());
                        questionBanks.setQuestionText(Jsoup.parse(subQuestion.getHtml()).text());
                        String questionHtml = AdvancedContentExtractor2.extractContentHTML(subQuestion.getHtml().replaceAll(">\\s+<", "><"));
                        questionBanks.setQuestionHtml(questionHtml);
                        questionBanks.setOptionsHtml("");
                        questionBanks.setOptions("");
                    }

                    questionBanks.setKnowledge("");
                    questionBanks.setAnswer("");
                    questionBanks.setScore("");
                    questionBanks.setUsageCount("0");
                    questionBanks.setParentId(MasterquestionBanks.getQuestionId());
                    save(questionBanks);
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }



    // 处理判断题的抽象方法
    private void processJudgmentQuestions(QuestionBankDto questionBankDto, String projectId, String subjectId,
                                          String[] projectSplit, String SessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, "判断题");

        AtomicInteger counter = new AtomicInteger(questionCount);
        questionBankDto.getQuestionCategory().getJudgmentQuestions().get("判断题").forEach(question -> {
            QuestionBanks questionBanks = new QuestionBanks();
            Document doc = Jsoup.parse(question);
            doc.outputSettings(new Document.OutputSettings().prettyPrint(false));
            Elements PElement = doc.select("p");
            StringBuilder optionHtml = new StringBuilder();
            StringBuilder questionHtml = new StringBuilder();
            StringBuilder option = new StringBuilder();

            questionBanks.setProjectId(projectId);
            questionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                    + SessionsNumber + "_" +
                    subjectSessionsById.getKmxh() + "_"+QuestionTypeEnum.getCodeByName("判断题")+"_" + counter.incrementAndGet());

            PElement.forEach(p -> {
                String text = p.text().trim();
                // 精确匹配段落开头（支持中文冒号和空格）
                if (text.startsWith("答案：")
                        || text.startsWith("分数：")
                        || text.startsWith("知识点：")) {

                } else if (text.matches("^[A-Z][\\.．,，].*")) {
                    // 处理选项
                    option.append(p.text());
                    optionHtml.append(p.outerHtml());
                } else {
                    // 保留题目正文
                    questionHtml.append(p.outerHtml());
                }
            });

            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.toString()));
            questionBanks.setQuestionText(doc.text());

            if (optionHtml.length() > 0) {
                questionBanks.setOptionsHtml(optionHtml.toString());
            } else {
                questionBanks.setOptionsHtml("<p><span>A．</span><span>正确 </span></p><p><span>B．</span><span>错误</span></p>");
            }

            questionBanks.setQuestionType("判断题");
            questionBanks.setSubjectId(subjectId);
            // 修改提取逻辑以支持嵌套标签结构
            String answerText = extractContent(doc, "答案：");
            String scoreText = extractContent(doc, "分数：");
            String knowledgeText = extractContent(doc, "知识点：");
            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.toString()));
            // 设置提取到的信息，如不存在则为空字符串
            questionBanks.setAnswer(answerText);
            questionBanks.setScore(scoreText);
            questionBanks.setKnowledge(knowledgeText);
            questionBanks.setChildCount("0");
            questionBanks.setUsageCount("0");
            questionBanks.setParentId("");
            save(questionBanks);
        });
    }

    // 处理单选题的抽象方法
    private void processSingleChoiceQuestions(QuestionBankDto questionBankDto, String projectId, String subjectId,
                                              String[] projectSplit, String SessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, "单项选择题");
        AtomicInteger counter = new AtomicInteger(questionCount);
        questionBankDto.getQuestionCategory().getSingleChoiceQuestions().get("单项选择题").forEach(question -> {
            QuestionBanks questionBanks = new QuestionBanks();
            Document doc = Jsoup.parse(question);
            doc.outputSettings(new Document.OutputSettings().prettyPrint(false));
            StringBuilder option = new StringBuilder();
            StringBuilder optionHtml = new StringBuilder();
            StringBuilder questionHtml = new StringBuilder();
            Elements PElement = doc.select("p");

            questionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                    + SessionsNumber + "_" +
                    subjectSessionsById.getKmxh() + "_"+QuestionTypeEnum.getCodeByName("单项选择题")+"_" + counter.incrementAndGet());

            PElement.forEach(p -> {
                String text = p.text().trim();
                // 精确匹配段落开头（支持中文冒号和空格）
                if (text.startsWith("答案：")
                        || text.startsWith("分数：")
                        || text.startsWith("知识点：")) {

                } else if (text.matches("^[A-Z][\\.．,，].*")) {
                    // 处理选项
                    option.append(p.text());
                    optionHtml.append(p.outerHtml());
                } else {
                    // 保留题目正文
                    questionHtml.append(p.outerHtml());
                }
            });

            // 修改提取逻辑以支持嵌套标签结构
            String answerText = extractContent(doc, "答案：");
            String scoreText = extractContent(doc, "分数：");
            String knowledgeText = extractContent(doc, "知识点：");

            // 设置提取到的信息，如不存在则为空字符串
            questionBanks.setAnswer(answerText);
            questionBanks.setScore(scoreText);
            questionBanks.setKnowledge(knowledgeText);
            questionBanks.setProjectId(projectId);
            questionBanks.setOptions(option.toString());
            questionBanks.setQuestionText(PElement.get(0).text());
            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.toString()));
            questionBanks.setOptionsHtml(AdvancedContentExtractor2.removePStyles2(optionHtml.toString()));
            questionBanks.setQuestionType("单项选择题");
            questionBanks.setSubjectId(subjectId);
            questionBanks.setChildCount("0");
            questionBanks.setUsageCount("0");
            questionBanks.setParentId("");
            save(questionBanks);
        });
    }

    // 处理多选题的抽象方法
    private void processMultipleChoiceQuestions(QuestionBankDto questionBankDto, String projectId, String subjectId,
                                                String[] projectSplit, String SessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, "多项选择题");
        AtomicInteger counter = new AtomicInteger(questionCount);
        questionBankDto.getQuestionCategory().getMultipleChoiceQuestions().get("多项选择题").forEach(question -> {
            QuestionBanks questionBanks = new QuestionBanks();
            Document doc = Jsoup.parse(question);
            doc.outputSettings(new Document.OutputSettings().prettyPrint(false));
            Elements PElement = doc.select("p");
            StringBuilder questionHtml = new StringBuilder();
            StringBuilder option = new StringBuilder();
            StringBuilder optionHtml = new StringBuilder();

            questionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                    + SessionsNumber + "_" +
                    subjectSessionsById.getKmxh() + "_"+QuestionTypeEnum.getCodeByName("多项选择题")+"_" + counter.incrementAndGet());

            PElement.forEach(p -> {
                String text = p.text().trim();
                // 精确匹配段落开头（支持中文冒号和空格）
                if (text.startsWith("答案：")
                        || text.startsWith("分数：")
                        || text.startsWith("知识点：")) {

                } else if (text.matches("^[A-Z][\\.．,，].*")) {
                    // 处理选项
                    option.append(p.text());
                    optionHtml.append(p.outerHtml());
                } else {
                    // 保留题目正文
                    questionHtml.append(p.outerHtml());
                }
            });
            // 修改提取逻辑以支持嵌套标签结构
            String answerText = extractContent(doc, "答案：");
            String scoreText = extractContent(doc, "分数：");
            String knowledgeText = extractContent(doc, "知识点：");

            // 设置提取到的信息，如不存在则为空字符串
            questionBanks.setAnswer(answerText);
            questionBanks.setScore(scoreText);
            questionBanks.setKnowledge(knowledgeText);
            questionBanks.setProjectId(projectId);
            questionBanks.setOptions(option.toString());
            questionBanks.setQuestionText(PElement.get(0).text());
            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.toString()));
            questionBanks.setOptionsHtml(AdvancedContentExtractor2.removePStyles2(optionHtml.toString()));
            questionBanks.setQuestionType("多项选择题");
            questionBanks.setSubjectId(subjectId);
            questionBanks.setUsageCount("0");
            questionBanks.setChildCount("0");
            questionBanks.setParentId("");
            save(questionBanks);
        });
    }

    // 处理填空题的抽象方法
    private void processFillBlankQuestions(QuestionBankDto questionBankDto, String projectId, String subjectId,
                                           String[] projectSplit, String SessionsNumber, SubjectSessions subjectSessionsById) {
        int questionCount = getQuestionCountBySubjectIdAndType(subjectId, "填空题");
        AtomicInteger counter = new AtomicInteger(questionCount);
        questionBankDto.getQuestionCategory().getBlankQuestion().get("填空题").forEach(question -> {
            QuestionBanks questionBanks = new QuestionBanks();
            Document doc = Jsoup.parse(question);
            doc.outputSettings(new Document.OutputSettings().prettyPrint(false));
            Elements PElement = doc.select("p");

            // 计算括号数量
            String questionText = doc.text();
            int bracketCount = countEmptyBrackets(questionText);

            questionBanks.setProjectId(projectId);
            questionBanks.setQuestionId("Z_" + projectSplit[0] + "_"
                    + SessionsNumber + "_" +
                    subjectSessionsById.getKmxh() + "_"+QuestionTypeEnum.getCodeByName("填空题")+"_" + counter.incrementAndGet());

            StringBuilder questionHtml = new StringBuilder();
            PElement.forEach(p -> {
                String text = p.text();
                if (!(text.startsWith("分数：") || text.startsWith("答案：") || text.startsWith("知识点："))) {
                    questionHtml.append(p.outerHtml());
                }
            });
            questionBanks.setQuestionHtml(AdvancedContentExtractor2.extractContentHTML(questionHtml.toString()));
            questionBanks.setQuestionText(doc.text());
            questionBanks.setQuestionType("填空题");
            questionBanks.setSubjectId(subjectId);
            questionBanks.setOptions("");
            questionBanks.setOptionsHtml("");
            questionBanks.setChildCount(String.valueOf(bracketCount));
            // 修改提取逻辑以支持嵌套标签结构
            String answerText = extractContent(doc, "答案：");
            String scoreText = extractContent(doc, "分数：");
            String knowledgeText = extractContent(doc, "知识点：");
            questionBanks.setUsageCount("0");
            // 设置提取到的信息，如不存在则为空字符串
            questionBanks.setAnswer(answerText);
            questionBanks.setScore(scoreText);
            questionBanks.setKnowledge(knowledgeText);
            questionBanks.setParentId("");
            save(questionBanks);
        });
    }
    private QuestionHtml getOptionsHtml(String html) {
      Document doc = Jsoup.parse(html);
      Elements PElement = doc.select("p");
      StringBuilder optionHtml = new StringBuilder();
      StringBuilder questionHtml = new StringBuilder();
      StringBuilder option = new StringBuilder();

      PElement.forEach(p -> {
          String text = p.text().trim();
          // 精确匹配段落开头（支持中文冒号和空格）
          if (text.startsWith("答案：")
                  || text.startsWith("分数：")
                  || text.startsWith("知识点：")) {

          } else if (text.matches("^[A-Z][\\.．,，].*")) {
              // 处理选项
              option.append(p.text());
              optionHtml.append(p.outerHtml());
          } else {
              // 保留题目正文
              questionHtml.append(p.outerHtml());
          }
      });
      QuestionHtml questionHtml1 = new QuestionHtml();
      questionHtml1.setQuestionHtml(questionHtml.toString());
      questionHtml1.setOptionHtml(optionHtml.toString());
      questionHtml1.setQuestionText(Jsoup.parse(questionHtml.toString()).text());
      questionHtml1.setOptions(option.toString());
      return questionHtml1;
  }
    @Data
    public static class QuestionHtml {
        private String questionHtml;
        private String optionHtml;
        private String questionText;
        private String options;
    }


    // 添加通用内容提取方法
    private String extractContent(Document doc, String prefix) {
        // 查找包含前缀的父级元素
        Elements parentElements = doc.select(String.format(":containsOwn(%s)", prefix)).parents();

        if (parentElements.isEmpty()) {
            System.out.println("未找到包含前綴的父元素：" + prefix);
            return "";
        }

        // 获取父元素完整文本
        String fullText = parentElements.first().text();
        System.out.println("父元素文本：" + fullText);

        // 改进后的正则表达式，允许标签分隔
        Pattern pattern = Pattern.compile(Pattern.quote(prefix) + "[^\\d\\p{L}]*([\\d\\p{L}]+)");
        Matcher matcher = pattern.matcher(fullText);

        if (matcher.find()) {
            String result = matcher.group(1).trim();
            System.out.println("最终提取結果：" + result);
            return result;
        }

        return "";
    }
    /**
     * 根据科目id获取题目
     * @param subjectId
     * @return
     */
    @Override
    public List<QuestionBanks> getQuestionBanksBySubjectId(String subjectId) {
        QueryWrapper<QuestionBanks> QuestionBanksQueryWrapper = new QueryWrapper<>();
        QuestionBanksQueryWrapper.eq("subject_id", subjectId);
        List<QuestionBanks> QuestionBanksList = questionBankMapper.selectList(QuestionBanksQueryWrapper);
        return QuestionBanksList;

    }

    @Override
    public IPage<QuestionVO> search(QuestionDTO questionDTO) {
        // 创建分页对象
        IPage<QuestionVO> page = new Page<>(questionDTO.getPageNum(), questionDTO.getPageSize());
        QueryWrapper<QuestionVO> wrapper = new QueryWrapper<>();

        // 项目ID精确查询
        if (!StringUtils.isEmpty(questionDTO.getProjectId())) {
            wrapper.eq("p.project_id", questionDTO.getProjectId());
        }

        // 科目ID精确查询
        if (!StringUtils.isEmpty(questionDTO.getSubjectId() )) {
            wrapper.eq("s.subject_id", questionDTO.getSubjectId());
        }



        // 题目类型精确查询
        if (!StringUtils.isEmpty(questionDTO.getQuestionType())) {
            wrapper.eq("q.question_type", questionDTO.getQuestionType());
        }

        // 题目内容模糊查询
        if (!StringUtils.isEmpty(questionDTO.getQuestionContent())) {
            wrapper.like("q.question_text", questionDTO.getQuestionContent());
        }


        // 执行分页查询（使用自定义SQL）
        return questionBankMapper.searchQuestions(page, wrapper);

    }

    @Override
    public Map<String, Map<String, Integer>> getKnowledgeQuestionStats(String subjectId) {
        List<Map<String, Object>> rawData = baseMapper.countQuestionsByKnowledge(subjectId);

        Map<String, Map<String, Integer>> result = new HashMap<>();

        for (Map<String, Object> item : rawData) {
            String knowledge = (String) item.get("knowledge");
            String questionType = (String) item.get("question_type");
            Integer count = (Integer) item.get("count");

            result.computeIfAbsent(knowledge, k -> new HashMap<>())
                    .put(questionType, count);
        }
        return result;
    }

    @Override
    public List<QuestionBanks> getQuestionsByTypeAndParentId(String subjectId, String questionType) {
        // 找出指定类型的题目以及子题
        List<QuestionBanks> questionBanks = questionBankMapper.selectList(new QueryWrapper<QuestionBanks>().eq("subject_id", subjectId).eq("question_type", questionType).eq("parent_id",""));
        // 递归获取子题目
        List<QuestionBanks> allChildQuestions = new ArrayList<>();
        for (QuestionBanks question : questionBanks) {
                allChildQuestions.addAll(getChildQuestions(question.getQuestionId()));
        }
        questionBanks.addAll(allChildQuestions);
        return questionBanks;
    }

    @Override
    public void deleteBySubjectQuestion(String subjectId) {
        // 根据科目ID删除题目
        questionBankMapper.delete(new QueryWrapper<QuestionBanks>().eq("subject_id", subjectId));

    }

    // 递归获取子题目
    private List<QuestionBanks> getChildQuestions(String parentId) {
        QueryWrapper<QuestionBanks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        return questionBankMapper.selectList(queryWrapper);
    }

    /**
     * 根据科目id获取题目数量
     * @param subjectId
     * @return
     */
    public int getQuestionCountBySubjectId(String subjectId) {
        QueryWrapper<QuestionBanks> wrapper = new QueryWrapper<>();
        wrapper.eq("subject_id", subjectId)
                .eq("parent_id", "");

        return questionBankMapper.selectCount(wrapper);
    }

    public int getQuestionCountBySubjectIdAndType(String subjectId, String questionType) {
        QueryWrapper<QuestionBanks> wrapper = new QueryWrapper<>();
        wrapper.eq("subject_id", subjectId)
                .eq("question_type", questionType)
                .eq("parent_id", "");

        return questionBankMapper.selectCount(wrapper);
    }
    // 计算空括号数量的辅助方法
    private int countEmptyBrackets(String text) {
        int bracketCount = 0;
        int openBracketIndex = -1;

        for (int i = 0; i < text.length(); i++) {
            char ch = text.charAt(i);
            if (ch == '（' || ch == '(') {
                openBracketIndex = i;
            } else if ((ch == '）' || ch == ')') && openBracketIndex != -1) {
                // 检查括号内是否只有空格或没有内容
                String contentInsideBrackets = text.substring(openBracketIndex + 1, i);
                if (contentInsideBrackets.trim().isEmpty()) {
                    bracketCount++;
                }
                openBracketIndex = -1; // 重置
            }
        }
        return bracketCount;
    }

    /**
     * 根据抽取配置抽取题目
     * @param configs 抽取配置列表
     * @return 抽取到的题目列表
     */
    @Transactional
    public List<QuestionBanks> extractQuestions(List<ExtractionConfig> configs) {
        List<QuestionBanks> result = new ArrayList<>();

        for (ExtractionConfig config : configs) {
            List<QuestionBanks> extracted = extractQuestionsByConfig(config);
            result.addAll(extracted);
        }

        return result;
    }

    /**
     * 根据单个配置抽取题目
     * @param config 抽取配置
     * @return 抽取到的题目列表
     */
    private List<QuestionBanks> extractQuestionsByConfig(ExtractionConfig config) {
        // 1. 获取指定知识点和题型的所有题目，按使用次数排序
        List<QuestionBanks> allQuestions = findByKnowledgeAndType(
                config.getKnowledge(), config.getQuestionType());

        if (allQuestions.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 将题目分为未使用过的和使用过的
        List<QuestionBanks> unusedQuestions = new ArrayList<>();
        List<QuestionBanks> usedQuestions = new ArrayList<>();

        for (QuestionBanks question : allQuestions) {
            if (question.getUsageCount() == null || Integer.parseInt(question.getUsageCount()) == 0) {
                unusedQuestions.add(question);
            } else {
                usedQuestions.add(question);
            }
        }

        // 3. 随机打乱未使用题目列表
        Collections.shuffle(unusedQuestions);

        // 4. 先抽取未使用过的题目
        List<QuestionBanks> selectedQuestions = new ArrayList<>();
        int needed = config.getCount();

        if (unusedQuestions.size() >= needed) {
            selectedQuestions.addAll(unusedQuestions.subList(0, needed));
        } else {
            selectedQuestions.addAll(unusedQuestions);
            needed -= unusedQuestions.size();

            // 5. 如果未使用题目不足，则从使用过的题目中抽取使用次数最少的
            if (needed > 0 && !usedQuestions.isEmpty()) {
                // 找出使用次数最少的题目
                int minUsageCount = usedQuestions.stream()
                        .mapToInt(q -> Integer.parseInt(q.getUsageCount()))
                        .min()
                        .orElse(0);

                List<QuestionBanks> leastUsedQuestions = usedQuestions.stream()
                        .filter(q -> Integer.parseInt(q.getUsageCount()) == minUsageCount)
                        .collect(Collectors.toList());

                // 随机打乱使用次数最少的题目
                Collections.shuffle(leastUsedQuestions);

                // 抽取所需数量的题目
                int toTake = Math.min(needed, leastUsedQuestions.size());
                selectedQuestions.addAll(leastUsedQuestions.subList(0, toTake));
            }
        }

        // 6. 更新题目使用次数
        for (QuestionBanks question : selectedQuestions) {
           incrementUsageCount(question.getQuestionId());
        }

        return selectedQuestions;
    }

    /**
     * 获取题目的使用次数
     * @param questionId 题目ID
     * @return 使用次数
     */
    public int getQuestionUsageCount(String questionId) {
        QuestionBanks question = findByQuestionId(questionId);
        return question != null ? (question.getUsageCount() != null ? Integer.parseInt(question.getUsageCount()) : 0) : 0;
    }

    /**
     * 重置题目的使用次数
     * @param questionId 题目ID
     */
    public void resetUsageCount(String questionId) {
        updateUsageCount(questionId, 0);
    }

    /**
     * 重置所有题目的使用次数
     */
    public void resetAllUsageCounts() {
        // 这里需要实现一个批量重置的方法
        // 实际实现可能需要根据具体需求调整
    }




    public List<QuestionBanks> findByKnowledgeAndType(String knowledge, String questionType) {
        QueryWrapper<QuestionBanks> wrapper = new QueryWrapper<>();
        wrapper.eq("knowledge", knowledge)
                .eq("question_type", questionType)
                .orderByAsc("usage_count");
        return questionBankMapper.selectList(wrapper);
    }
    public QuestionBanks findByQuestionId(String questionId) {
        QueryWrapper<QuestionBanks> wrapper = new QueryWrapper<>();
        wrapper.eq("question_id", questionId);
        return questionBankMapper.selectOne(wrapper);
    }
    public void  updateUsageCount(String questionId, int newCount) {
        QuestionBanks questionBanks = findByQuestionId(questionId);
        questionBanks.setUsageCount(String.valueOf(newCount));
        questionBankMapper.updateById(questionBanks);
    }
    public  void incrementUsageCount(String questionId) {
        QuestionBanks questionBanks = findByQuestionId(questionId);
        int currentCount = Integer.parseInt(questionBanks.getUsageCount());
        updateUsageCount(questionId, currentCount + 1);
    }
    // 根据题目id 递归查询所有子题目
    public List<QuestionBanks> findByParentId(String parentId) {
        QueryWrapper<QuestionBanks> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", parentId);
        return questionBankMapper.selectList(wrapper);
    }
    public QuestionBanks getByQuestionId(String questionId) {
        return questionBankMapper.selectOne(new QueryWrapper<QuestionBanks>().eq("question_id", questionId));
    }
    public boolean updateScoreByQuestionId(QuestionBanks questionBanks) {
        return update(
                new LambdaUpdateWrapper<QuestionBanks>()
                        .eq(QuestionBanks::getQuestionId, questionBanks.getQuestionId())
                        // 按需更新字段（值不为null时更新）
                        .set(questionBanks.getScore() != null, QuestionBanks::getScore, questionBanks.getScore()));
    }
}
